package com.vedeng.study.service;

import com.alibaba.fastjson.JSON;
import com.comment.common.RestfulResult;
import com.comment.dto.CommentDTO;
import com.comment.dto.CommentRequest;
import com.vedeng.study.feign.BlogCommentFeign;
import com.vedeng.study.mapper.Blog1Mapper;
import com.vedeng.study.mapper.Blog2Mapper;
import com.vedeng.study.mapper.BlogContentMapper;
import com.vedeng.study.mapper.BlogDetailMapper;
import com.vedeng.study.model.*;
import com.vedeng.study.model.dto.BlogDTO;
import com.vedeng.study.model.dto.BlogMessage;
import com.vedeng.study.request.BlogVO;
import com.vedeng.study.util.SnowFlake;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.BlockingQueue;
import java.util.stream.Collectors;

/**
 * @Description:
 * @author: Thresh.xie
 * @Date: 2021/12/13
 */
@Service
public class BlogServiceImpl implements BlogService {
    @Resource
    private Blog1Mapper blog1Mapper;
    @Resource
    private Blog2Mapper blog2Mapper;
    @Resource
    private BlogContentMapper blogContentMapper;
    @Resource
    private BlogDetailMapper blogDetailMapper;
    @Resource
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private BlogCommentFeign blogCommentFeign;

    @Override
//    @Transactional(rollbackFor = Exception.class)
    public void insert(BlogVO blogVO) {
        Long blogId = SnowFlake.generatorId();
        int code = Integer.parseInt(Long.toString(blogId % 3));

        Blog blog = new Blog();
        blog.setBlogid(blogId);
        blog.setBlogtitle(blogVO.getBlogtitle());
        blog.setBlogauthor(blogVO.getBlogauthor());
        blog.setCreator("创建者");
        blog.setUpdater("修改者");
        blog.setIsdel("0");
        blog.setAddtime(new Date());
        blog.setModtime(new Date());

        Blog1 blog1 = new Blog1();
        Blog2 blog2 = new Blog2();

        switch (code) {
            case 0:
            case 1:
                BeanUtils.copyProperties(blog, blog1);
                blog1Mapper.insert(blog1);
                break;
            case 2:
            default:
                BeanUtils.copyProperties(blog, blog2);
                blog2Mapper.insert(blog2);
        }

        BlogContent blogContent = new BlogContent();
        blogContent.setBlogid(blogId);
        blogContent.setBlogcontent(blogVO.getBlogContent());
        blogContentMapper.insert(blogContent);


        BlogMessage blogMessage = new BlogMessage();
        blogMessage.setType("insert");
        blogMessage.setBlogVO(blogVO);

        //向mq发送新增博客的信息,给搜索中心使用
        rabbitTemplate.convertAndSend("yanaDirectExchange", "yanaDirectQueue0", JSON.toJSONString(blogMessage));

    }

    @Override
    public void delete(BlogVO blogVO) {
        Long blogId = blogVO.getBlogid();
        Blog blog = new Blog();
        blog.setBlogid(blogId);
        blog.setIsdel("1");

        //更新博客主属性表
        updateBlog(blogId, blog);
        //删除时无需涉及博客内容表

        BlogMessage blogMessage = new BlogMessage();
        blogMessage.setType("delete");
        blogMessage.setBlogVO(blogVO);

        //向mq发送修改博客的信息,给搜索中心使用
        rabbitTemplate.convertAndSend("yanaDirectExchange", "yanaDirectQueue0", JSON.toJSONString(blogMessage));

    }

    @Override
    public void update(BlogVO blogVO) {
        Long blogId = blogVO.getBlogid();
        Blog blog = new Blog();
        blog.setBlogid(blogId);
        blog.setBlogtitle(blogVO.getBlogtitle());
        blog.setBlogauthor(blogVO.getBlogauthor());
        blog.setUpdater("修改者");
        blog.setModtime(new Date());

        //更新博客主属性表
        updateBlog(blogId, blog);
        //当博客内容发生变化时再更新博客内容表
        //if (!blogVO.getOldBlogContent().equals(blogVO.getBlogContent())) {
            BlogContent blogContent = new BlogContent();
            blogContent.setBlogid(blogId);
            blogContent.setBlogcontent(blogVO.getBlogContent());
            BlogContentExample blogContentExample = new BlogContentExample();
            blogContentExample.createCriteria().andBlogidEqualTo(blogId);
            blogContentMapper.updateByExampleSelective(blogContent, blogContentExample);
        //}

        BlogMessage blogMessage = new BlogMessage();
        blogMessage.setType("update");
        blogMessage.setBlogVO(blogVO);
        //向mq发送修改博客的信息,给搜索中心使用
        rabbitTemplate.convertAndSend("yanaDirectExchange", "yanaDirectQueue0", JSON.toJSONString(blogMessage));
    }

    private void updateBlog(Long blogId, Blog blog) {
        Blog1 blog1 = new Blog1();
        Blog2 blog2 = new Blog2();
        int code = Integer.parseInt(Long.toString(blogId % 3));
        switch (code) {
            case 0:
            case 1:
                BeanUtils.copyProperties(blog, blog1);
                Blog1Example blog1Example = new Blog1Example();
                blog1Example.createCriteria().andBlogidEqualTo(blogId);
                blog1Mapper.updateByExampleSelective(blog1, blog1Example);
                break;
            case 2:
            default:
                BeanUtils.copyProperties(blog, blog2);
                Blog2Example blog2Example = new Blog2Example();
                blog2Example.createCriteria().andBlogidEqualTo(blogId);
                blog2Mapper.updateByExampleSelective(blog2, blog2Example);
        }
    }

    @Override
    public BlogVO blogDetail(Long blogId) {

        BlogVO blogVO;
        int code = Integer.parseInt(Long.toString(blogId % 3));
        switch (code) {
            case 0:
            case 1:
                blogVO = blogDetailMapper.queryByBlogIdFrom1(blogId);
                break;
            case 2:
            default:
                blogVO = blogDetailMapper.queryByBlogIdFrom2(blogId);
        }
        return blogVO;
    }


    @Override
    public List<BlogDTO> queryBlogList(BlogVO blogVO) {

        List<BlogDTO> blogDTOList = new ArrayList<>();
        Blog1Example blog1Example = new Blog1Example();
        blog1Example.createCriteria().andIsdelEqualTo("0").andBlogauthorEqualTo(blogVO.getBlogauthor());

        List<Blog1> blog1s = blog1Mapper.selectByExample(blog1Example);

        List<Long> blogIdList1 = new ArrayList<>();
        if (!CollectionUtils.isEmpty(blog1s)){
            blogIdList1 = blog1s.stream().map(Blog1::getBlogid).collect(Collectors.toList());
        }


        Blog2Example blog2Example = new Blog2Example();
        blog2Example.createCriteria().andIsdelEqualTo("0").andBlogauthorEqualTo(blogVO.getBlogauthor());

        List<Blog2> blog2s = blog2Mapper.selectByExample(blog2Example);

        if (CollectionUtils.isEmpty(blog1s) && CollectionUtils.isEmpty(blog2s)){
            return blogDTOList;
        }

        List<Long> blogIdList2 = new ArrayList<>();
        if (!CollectionUtils.isEmpty(blog2s)){
            blogIdList2 = blog2s.stream().map(Blog2::getBlogid).collect(Collectors.toList());
        }

        blogIdList1.addAll(blogIdList2);

        BlogContentExample blogContentExample = new BlogContentExample();
        blogContentExample.createCriteria().andBlogidIn(blogIdList1);

        List<BlogContent> blogContents = blogContentMapper.selectByExample(blogContentExample);

        Map<Long, String> contentMap = blogContents.stream().collect(Collectors.toMap(BlogContent::getBlogid, BlogContent::getBlogcontent));

        blog1s.stream().forEach(obj -> {
            BlogDTO dto = new BlogDTO();
            dto.setBlogId(obj.getBlogid());
            dto.setBlogTitle(obj.getBlogtitle());
            dto.setBlogContent(contentMap.get(obj.getBlogid()));
            blogDTOList.add(dto);
        });

        blog2s.stream().forEach(obj -> {
            BlogDTO dto = new BlogDTO();
            dto.setBlogId(obj.getBlogid());
            dto.setBlogTitle(obj.getBlogtitle());
            dto.setBlogContent(contentMap.get(obj.getBlogid()));
            blogDTOList.add(dto);
        });
        return blogDTOList;
    }


    @Override
    public List<CommentDTO> queryBlogComment(CommentRequest request) {
        List<CommentDTO> commentDTOList = new ArrayList<>();
        try {
            commentDTOList = blogCommentFeign.queryAllComment(request);
        } catch (Exception e) {
            e.printStackTrace();
            return commentDTOList;
        }
        return commentDTOList;
    }


    @Override
    public String addComments(BlogVO blogVO) {
        CommentRequest request = new CommentRequest();
        request.setBlogId(blogVO.getBlogid());
        request.setContent(blogVO.getComment());
        request.setUserId(Integer.parseInt(blogVO.getBlogauthor()));
        request.setUserName(blogVO.getUserName());
        RestfulResult restfulResult = blogCommentFeign.addComment(request);
        return restfulResult.getMessage();

    }
}
